<script setup lang='ts'>
// 自定义 规则
interface MarKerDetailHTML {
  detail: {
    markerId: number,
    latitude: number,
    longitude: number
  }
}
interface Search {
  title: string,
  path: string,
  promise?: Promise<Search>,
  imageUrl: string
}
import { onMounted, ref, reactive, computed, getCurrentInstance, defineExpose, watch, nextTick } from 'vue';
import { onShow, onShareAppMessage } from '@dcloudio/uni-app'
import Operator from './component/operator.vue';
import { showToast, authAdmin, authManage, currentLocation, debounce } from '@/public';
import { useSearchStore, useMarkerStore, useMapStore, useTeamStore, usePdcStore, useUserStore } from '@/store/index'
import Search from './component/search.vue';
import MarkerOperate from './component/markerOperate.vue';
import SearchHave from './component/searchHave.vue';
import { https } from '@/api/api'
import TramList from './component/tramList.vue'
import { colorList } from '../list';
import Tabbar from '@/components/tabbar/index.vue'
import { getDistance, countDistance } from '@/public/amapFun'
// const { TopMap } = require('../../public/amap/mapWx')
const searchStore = useSearchStore();
const markerStore = useMarkerStore();
const mapStore = useMapStore();
const teamStore = useTeamStore();
const pdcStore = usePdcStore();
const userStore = useUserStore();
const _that = getCurrentInstance()?.appContext.config.globalProperties;
const statusBottomHeight = ref(0);

const userData = computed(() => uni.getStorageSync('userData'));
//uni.hideTabBar();
uni.getSystemInfo({
  success: function (info) {
    // 获取安全区域的 bottom 值，单位px
    //#ifndef H5
    statusBottomHeight.value = info?.safeAreaInsets?.bottom || 0
    //#endif
  }
});
/**
 * @property 变量
 */
// 经纬度
const lnglat: LngLat = reactive({
  longitude: 116.397761,
  latitude: 39.908273
})
// 原始 list 
const list = ref<Array<ListItem>>([])
// 标记点
const markers = ref<Array<MarkerItem>>([])
// 地图实例
const mapCxt = ref<any>(null);
// 缩放级别
const mapScale = ref(11);
// 添加点标记
const isAddMarker = ref<boolean>(false);
// 展示可操作项
const idMarkerItem = ref(false);
// 要添加的marker
const soonAddMarker = ref<MarkerItem>();
// 搜索组件ref
const searRef = ref();
// 常显还是点击显示
const isBubble = ref<boolean>(false) //false:点击显示
//选择团队的ref 
const teamRef = ref();
// 搜索已有的marker
const isSearchHave = ref<boolean>(false);
// 足迹列表
const footprintList = ref<Array<FootprintItem>>([]);
// 设置好的数据
const marList = ref<Array<MarkerItem>>([]);
// 旧的 缩放级别
const oldScale = ref<number>(11);
// 旧的 中心点
const oldCenterLnglat = ref<oldCenterlnglat>({
  lat: 0,
  lng: 0
})
// 记录最大的缩放值
const recordMaxScale = ref<number>(11);
// 用户当前位置
const userInfoLnglat = ref<oldCenterlnglat>({
  lat: 0,
  lng: 0
})
/**
 * @property  所有请求以api开头 如:apiDataInfo
 */
const apiMarkerList = (): Promise<Array<ListItem>> => {
  return new Promise(async (resolve) => {
    const res = await https({
      mode: 'marker',
      name: 'apiGetTeamMarker',
    })
    resolve(res.data.list)
  })

}
// 管理者通过团队 获取marker表
const apiGetManageTeamMarker = (): Promise<Array<ListItem>> => {
  return new Promise(async (resolve) => {
    if (!teamStore.teamId) {
      resolve([])
      return;
    }
    const res = await https({
      mode: 'marker',
      name: 'apiGetManageTeamMarker',
      data: {
        team: teamStore.teamId + ''
      }
    })
    resolve(res.data.list)
  })
}
//指定地区获取标记点
const apiAreaMarker = (): Promise<Array<number>> => {
  return new Promise(async (resolve) => {
    const res = await https({
      mode: 'marker',
      name: 'apiGetRangeMarker',
      data: {
        type: pdcStore.pcdId.d ? '3' : pdcStore.pcdId.c ? '2' : '1',
        area: pdcStore.pcdId.d ? pdcStore.pcdId.d + '' : pdcStore.pcdId.c ? pdcStore.pcdId.c + '' : pdcStore.pcdId.p + '',
      }
    })
    if (res.code !== 0) return resolve([]);
    const markerItem = markerStore.markersList.find(item => item.mid === res.data.list[0]);
    lnglat.latitude = Number(markerItem?.lat)
    lnglat.longitude = Number(markerItem?.lng)
    mapScale.value = 5
    oldCenterLnglat.value = {
      lng: lnglat.latitude,
      lat: lnglat.longitude
    }
    resolve(res.data.list)
  })
}
//
/**
 * @property 自定义事件 以事件名开头 如: clickButton,inputDev
 */

// 创建点标记列表
const createMarker = async () => {
  // 通过地区 进行数据获取
  if (pdcStore.pcdId.p && pdcStore.pcdId.p !== 'all') {
    const listId = await apiAreaMarker();
    list.value = markerStore.markersList.filter(item => {
      return listId.indexOf(item.mid) !== -1
    })
    markerStore.operational = list.value
    return areaMarker();

  }
  // 员工数据获取
  if (userData.value.type === 1) list.value = await apiMarkerList();
  //管理层数据获取
  if (userData.value.type !== 1) list.value = await apiGetManageTeamMarker();
  markerStore.markersList = list.value;
  markerStore.operational = list.value;
  // 获得的数据进行处理
  markerDataHandle();
}
// 特殊处理 通过地区查询出的
const areaMarker = () => {
  addFormatmarker();
  // 添加
  mapCxt.value.addMarkers({
    markers: marList.value,
    clear: true,
    success: () => {
      uni.hideLoading();
    }
  })
}
// 格式化 标记点添加
const addFormatmarker = () => {
  marList.value = [];
  list.value?.map((item, i) => {
    const data = mapStore.formatMarker(item)
    marList.value.push({
      ...data,
      iconPath: colorPath(item.showsize + ''),
      callout: {
        ...data.callout as Callout,
        display: isBubble.value ? 'ALWAYS' : 'BYCLICK'
      }
    })
  })
}

// 获取标记点的数据处理
const markerDataHandle = async () => {
  addFormatmarker();
  // 手动出入标记点移动的回调
  handMovementChange();
}
// 点击点标记
const clickMarker = async (e: MarKerDetailHTML) => {

  const markerId = e?.detail?.markerId;
  if (markerId === 10086) return;
  if (markerId === soonAddMarker.value?.id) return;
  const code = await markerStore.getMarkerInfo(markerId + '');
  if (code !== 0) return;
  idMarkerItem.value = true
  const item = list.value.find(item => item.id === markerId);
  if (item) {
    searchStore.setItem(item)
  }
}
// 要筛选出的颜色路径
const colorPath = (id: string) => {
  const path = colorList.find(item => item.id === id)?.color
  return `../../static/${path || 'red'}.png`
}
// 添加标记点
const clickAddMarker = (e: MarKerDetailHTML) => {
  if (!isAddMarker.value) return;
  if (!soonAddMarker.value) {
    soonAddMarker.value = {
      latitude: Number(e.detail.latitude),
      longitude: Number(e.detail.longitude),
      id: Math.floor(Math.random() * 100) + 1 + 10098,
      iconPath: '../../static/current-marker.png',
      width: '30',
      height: '30',
      zIndex: 2000,
    }
    mapCxt.value.addMarkers({
      markers: [soonAddMarker.value],
      clear: true,
    })
    console.log(soonAddMarker.value)
  } else {
    // 进行平移
    translationMarker({
      latitude: e.detail.latitude,
      longitude: e.detail.longitude
    })
  }
  searRef.value.reverseAddressResolution(e.detail.latitude, e.detail.longitude);
}
// 平移标记点
const translationMarker = (lnglat: LngLat) => {
  mapCxt.value.translateMarker({
    markerId: soonAddMarker.value?.id,
    destination: {
      latitude: lnglat.latitude,
      longitude: lnglat.longitude,
    },
    autoRotate: false,
    rotate: 0,
    duration: 100,
  })
}
// 对数据进行刷新
const clickRefresh = async () => {
  await createMarker();
}
// // 初始化当前位置，并设置zoom 及中心位置
const clickPosition = async () => {
  await myAddress()
  // 获取当前缩放级别
  const { scale }: { scale: number } = await mapCxt.value.getScale();
  mapScale.value = scale
  //设置级别
  setTimeout(() => {
    mapScale.value = 17
  }, 500)
  // 位置移动
  mapCxt.value.moveToLocation()
}
// // 搜索
const clickSearch = () => {
  isSearchHave.value = true
}
// 画点
const clickPoint = () => {
  isAddMarker.value = true;
  // searRef.value.reverseAddressResolution(userMarker.value?.latitude, userMarker.value?.longitude)
  // 将当前位置 创建标记点
  clickAddMarker({
    detail: {
      latitude: lnglat?.latitude as number,
      longitude: lnglat?.longitude as number,
      markerId: 0
    }

  })
}
// 跳转第三方导航
const navThirdParty = () => {
  mapCxt.value.openMapApp({
    longitude: Number(markerStore.marker.lng),
    latitude: Number(markerStore.marker.lat),
    destination: markerStore.marker?.alias,
  })
}
// 关闭标记点
const closeMarker = () => {
  idMarkerItem.value = false;
  markerStore.initMarker();
  markerStore.setPicList([]);
}
// 显示标记点
const closeShowMarker = () => {
  isAddMarker.value = false;
  mapStore.isRefresh=true;
  if (soonAddMarker.value) {
    mapCxt.value.removeMarkers({
      markerIds: [soonAddMarker.value?.id]
    })
    soonAddMarker.value = undefined;
  }

  clickRefresh();
}
// 点击数据项
const clickDataItem = (LngLat: LngLat) => {
  translationMarker({
    latitude: LngLat?.lat as number,
    longitude: LngLat?.lng as number,
  })
};
// 删除 某一个 marker
// const deleteMarker = (id: number) => {
//   mapCxt.value.removeMarkers({
//     markerIds: [id]
//   })
//   idMarkerItem.value = false
// }
// 搜索出的哪一项
const clickSearchItem = async (e: MarKerDetailHTML) => {
  // 创建标记点
  mapCxt.value.removeMarkers({
    markers: [e.detail.markerId]
  })
  // 筛选出此项
  const items = marList.value.find(item => item.id === e.detail.markerId);
  // 创建标记点
  mapCxt.value.addMarkers({
    markers: [{
      ...items,
      joinCluster: true
    }]
  })
  clickMarker(e);
  lnglat.longitude = items?.longitude;
  lnglat.latitude = items?.latitude;
  // 获取当前缩放级别
  const { scale }: { scale: number } = await mapCxt.value.getScale();
  mapScale.value = scale
  //设置级别
  setTimeout(() => {
    mapScale.value = 17
  }, 500)

}
// 我的位置
const myAddress = async () => {
  const e: LngLat = await currentLocation() as LngLat;
  lnglat.longitude = e.lng as number;
  lnglat.latitude = e.lat as number;
  oldCenterLnglat.value = {
    lng: e.lng as number,
    lat: e.lat as number
  }
}
// 地缩放触发
const scaleChange = async (zoom: number, lng: number, lat: number, causedBy?: 'drag' | 'scale' | 'update' | 'title') => {
  let scale = Math.floor(zoom)
  if (causedBy !== 'title' && !mapStore.isRefresh) {
    if (scale < 7) scale = 7;
    if (scale > 11) return
    const is = countDistance({ lat1: lat, lng1: lng, lat2: oldCenterLnglat.value.lat, lng2: oldCenterLnglat.value.lng }, Math.floor(scale) as scaleType);

    if (causedBy === 'scale' || causedBy === 'update') {
      if (scale > 11 || recordMaxScale.value <= 7) return;
      // 判断当前缩放值 是否小于上一次 是则不执行
      if (scale > oldScale.value && recordMaxScale.value <= scale) return;
      else oldScale.value = scale;
      if (scale < recordMaxScale.value) recordMaxScale.value = scale;
    }
    if (causedBy === 'drag' || causedBy === 'update') {
      if (!is) return;
      else {
        // 判断是否已超出 最大值距离
        const isDis = countDistance({ lat1: lat, lng1: lng, lat2: oldCenterLnglat.value.lat, lng2: oldCenterLnglat.value.lng }, Math.floor(recordMaxScale.value) as scaleType);
        if (!isDis) return;
        recordMaxScale.value = scale
        // 记录已获取记录的中心点位置
        oldCenterLnglat.value = {
          lat: lat,
          lng: lng
        }
      }
    }
  }
  // 最小查1公里 最大查100公里
  uni.showLoading({
    title: '数据加载中...',
    mark: true
  })
  if(scale>11) scale==11
  const arrayMap = marList.value.filter(item => getDistance({ lat1: lat, lng1: lng, lat2: item.latitude, lng2: item.longitude }, scale as scaleType)).map(item => ({
    ...item,
    joinCluster: scale <= 15,
    callout: {
      ...item.callout as Callout,
      display: isBubble.value ? 'ALWAYS' : 'BYCLICK'
    }
  }));
  mapStore.isRefresh=false
  // 初始化聚合点参数
  mapCxt.value.initMarkerCluster({
    gridSize: 40,
    success: () => {
      mapCxt.value.addMarkers({
        markers: arrayMap,
        clear: true,
        success: () => {
          uni.hideLoading();
        }
      })
    }
  })
}
// 地图视野发生变化
const mapviewChange = (e: any) => {
  if (isAddMarker.value) return;
  if (list.value.length === 0) return; //为空不执行 任何操作
  if (e.type === 'begin') return;  // 监听开始 不执行任何操作
  scaleChange(e.detail.scale, e.detail.centerLocation.longitude, e.detail.centerLocation.latitude, e.causedBy)
}
// 显示title 名称
const showCallout = async () => {
  isBubble.value = !isBubble.value;
  handMovementChange('title');
}
// 手动 触发地图 移动/拖拽函数
const handMovementChange = async (key?: 'title') => {
  // 获取当前中心点
  const centerLocation: LngLat = await mapCxt.value.getCenterLocation()
  // 地图当前缩放级别
  const scale: { scale: number } = await mapCxt.value.getScale();
  mapviewChange({
    type: 'end',
    causedBy: key || 'scale',
    detail: {
      centerLocation: {
        longitude: centerLocation.longitude,
        latitude: centerLocation.latitude
      },
      scale: scale.scale
    }
  })
}
const regionChangeMap = (e: any) => {
  debounce(() => mapviewChange(e))
}
// 全览
const clickOverview = async () => {
  const { scale }: { scale: number } = await mapCxt.value.getScale();
  mapScale.value = scale
  //设置级别
  setTimeout(() => {
    mapScale.value = 5
  }, 500)
}
/**
 * @property 内置方法
 */
// dom 加载完
onMounted(async () => {
  mapCxt.value = uni.createMapContext('map', _that);
  mapStore.setMapCtx(mapCxt.value)
  await myAddress();
  await userStore.apiLogin({
    callback: createMarker
  });
})
// 页面每次加载
onShow(() => {
  if (mapStore.isRefresh) {
    console.log('show')
    idMarkerItem.value = false;
    closeShowMarker();
  }
})
// 分享
onShareAppMessage((): Search => {
  const promise: Promise<Search> = new Promise(async (resolve) => {
    const res = await https({
      mode: 'marker',
      name: 'apiCreateShare',
      data: {
        mid: markerStore.marker.mid + ''
      }
    })

    if (res.code !== 0) {
      resolve({
        title: '分享失败',
        path: '/pages/sharePage/index',
        imageUrl: ''
      })
    } else {
      resolve({
        title: markerStore.marker.alias as string,
        path: `/pages/sharePage/index?t=${res.data.t}&d=${res.data.d}`,
        imageUrl: ''
      })
    }
  })
  return {
    title: '分享失败',
    path: '/pages/sharePage/index',
    imageUrl: '',
    promise,
  }
})

defineExpose({
  createMarker
})
</script>

<template>
  <page-meta
    :page-style="'overflow:' + (idMarkerItem || ((authAdmin() || authManage())) ? 'visible' : 'hidden')"></page-meta>
  <map name="map" class="w-[100vw] h-[100vh]" id="map" :longitude="lnglat.longitude" :latitude="lnglat.latitude"
    :markers="markers" @markertap="clickMarker" @tap="clickAddMarker" :scale="mapScale" @poitap="clickAddMarker"
    :polyline="footprintList" @regionchange="regionChangeMap" :show-location="true" :show-scale="true">
  </map>
  <Operator :isPdc="pdcStore.isPdc" @showBubble="showCallout" @refresh="clickRefresh" @position="clickPosition"
    @overview="clickOverview" @search="clickSearch" @point="clickPoint" />
  <!--添加标记点 -->
  <Search :isShow="isAddMarker" @close="closeShowMarker" ref="searRef" @click-item="clickDataItem" />
  <!-- 对标记点的操作 -->
  <MarkerOperate :isShow="idMarkerItem" @nav="navThirdParty" @close="closeMarker" />

  <!-- 头部业务经理或团队选择 -->
  <TramList v-if="(authAdmin() || authManage() || userStore.info?.tk)" ref="teamRef" @confim="createMarker"
    :title="userStore.info?.tk" />
  <!-- 搜索已有 -->
  <SearchHave v-if="isSearchHave" @click-item="clickSearchItem" @close="isSearchHave = false" />
  <Tabbar type="home" />
</template>
<style lang="scss" scoped></style>